package com.hc.app.frequencycontrol;

import cn.hutool.core.lang.Assert;
import com.hc.app.annatation.SupplierThrowWithoutParam;
import com.hc.app.dto.FrequencyControlDto;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * 限流工具类 提供编程式的限流调用方法
 */
public class FrequencyControlUtil {
    /**
     * 多限流策略的编程式调用方法调用方法
     *
     * @param strategyName         策略名称
     * @param frequencyControlList 频控列表 包含每一个频率控制的定义以及顺序
     * @param supplier             函数式入参-代表每个频控方法执行的不同的业务逻辑
     * @return 业务方法执行的返回值
     * @throws Throwable 被限流或者限流策略定义错误
     */
    public static <T, K extends FrequencyControlDto> T executeWithFrequencyControlList(String strategyName, List<K> frequencyControlList, SupplierThrowWithoutParam<T> supplier) throws Throwable {
        boolean existsFrequencyControlHasNullKey = frequencyControlList.stream().anyMatch(frequencyControl -> ObjectUtils.isEmpty(frequencyControl.getKey()));
        Assert.isFalse(existsFrequencyControlHasNullKey, "限流策略的Key字段不允许出现空值");
        AbstractFrequencyControl<K> frequencyController = FrequencyStrategyFactory.getFrequencyByName(strategyName);
        return frequencyController.executeWithFrequencyControlList(frequencyControlList, supplier);
    }
}
